package com.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.demo.mapper.AdminMapper;
import com.demo.pojo.entity.Admin;
import com.demo.pojo.dto.AdminListDTO;
import com.demo.service.AdminService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.security.MessageDigest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 管理员服务实现类
 */
@Service
public class AdminServiceImpl implements AdminService {
    
    @Autowired
    private AdminMapper adminMapper;
    
    @Override
    public IPage<AdminListDTO> getAdminList(Page<Admin> page, String adminNo, String adminName, String adminRole, Integer adminStatus) {
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        
        // 管理员账号模糊查询
        if (StringUtils.hasText(adminNo)) {
            queryWrapper.like("admin_no", adminNo);
        }
        
        // 管理员姓名模糊查询
        if (StringUtils.hasText(adminName)) {
            queryWrapper.like("admin_name", adminName);
        }
        
        // 角色精确查询
        if (StringUtils.hasText(adminRole)) {
            queryWrapper.eq("admin_role", adminRole);
        }
        
        // 状态精确查询
        if (adminStatus != null) {
            queryWrapper.eq("admin_status", adminStatus);
        }
        
        // 按创建时间降序排列
        queryWrapper.orderByDesc("create_time");
        
        // 执行分页查询
        IPage<Admin> adminPage = adminMapper.selectPage(page, queryWrapper);
        
        // 转换为DTO
        IPage<AdminListDTO> dtoPage = new Page<>();
        BeanUtils.copyProperties(adminPage, dtoPage);
        
        List<AdminListDTO> dtoList = adminPage.getRecords().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        
        dtoPage.setRecords(dtoList);
        
        return dtoPage;
    }
    
    @Override
    public Admin getAdminById(Long id) {
        return adminMapper.selectById(id);
    }
    
    @Override
    public Admin getAdminByNo(String adminNo) {
        return adminMapper.selectByAdminNo(adminNo);
    }
    
    @Override
    public Admin login(String adminNo, String password) {
        if (adminNo == null || adminNo.trim().isEmpty()) {
            throw new RuntimeException("管理员账号不能为空");
        }
        
        if (password == null || password.trim().isEmpty()) {
            throw new RuntimeException("密码不能为空");
        }
        
        Admin admin = getAdminByNo(adminNo);
        if (admin == null) {
            throw new RuntimeException("管理员账号不存在");
        }
        
        if (admin.getAdminStatus() == 0) {
            throw new RuntimeException("账号已被禁用");
        }
        
        // 兼容明文与历史32位MD5：优先明文，失败则尝试md5(password)
        String stored = admin.getAdminPassword();
        boolean match = password.equals(stored);
        if (!match && stored != null && stored.length() == 32) {
            match = md5(password).equalsIgnoreCase(stored);
        }
        if (!match) {
            throw new RuntimeException("密码错误");
        }
        
        return admin;
    }
    
    @Override
    public boolean addAdmin(Admin admin) {
        // 检查管理员账号是否已存在
        if (getAdminByNo(admin.getAdminNo()) != null) {
            throw new RuntimeException("管理员账号已存在");
        }
        
        // 不再加密，按明文保存
        
        // 设置创建时间
        admin.setCreateTime(new Date());
        admin.setUpdateTime(new Date());
        
        return adminMapper.insert(admin) > 0;
    }
    
    @Override
    public boolean updateAdmin(Admin admin) {
        // 检查管理员账号是否被其他管理员使用
        Admin existingAdmin = getAdminByNo(admin.getAdminNo());
        if (existingAdmin != null && !existingAdmin.getAdminId().equals(admin.getAdminId())) {
            throw new RuntimeException("管理员账号已被其他管理员使用");
        }
        
        // 如果密码不为空，按明文保存；为空则保留原密码
        if (!StringUtils.hasText(admin.getAdminPassword())) {
            // 如果密码为空，则不更新密码
            Admin oldAdmin = getAdminById(admin.getAdminId());
            if (oldAdmin != null) {
                admin.setAdminPassword(oldAdmin.getAdminPassword());
            }
        }
        
        // 设置更新时间
        admin.setUpdateTime(new Date());
        
        return adminMapper.updateById(admin) > 0;
    }
    
    @Override
    public boolean deleteAdmin(Long id) {
        return adminMapper.deleteById(id) > 0;
    }
    
    @Override
    public boolean deleteAdminByNo(String adminNo) {
        // 先根据账号查询管理员
        Admin admin = getAdminByNo(adminNo);
        if (admin == null) {
            throw new RuntimeException("管理员不存在");
        }
        // 再根据ID删除
        return adminMapper.deleteById(admin.getAdminId()) > 0;
    }
    
    @Override
    public boolean deleteAdmins(List<Long> ids) {
        return adminMapper.deleteBatchIds(ids) > 0;
    }
    
    /**
     * 将Admin实体转换为AdminListDTO
     */
    private AdminListDTO convertToDTO(Admin admin) {
        AdminListDTO dto = new AdminListDTO();
        BeanUtils.copyProperties(admin, dto);
        
        // 状态转换
        if (admin.getAdminStatus() != null) {
            dto.setAdminStatusText(admin.getAdminStatus() == 1 ? "启用" : "禁用");
        }
        
        return dto;
    }
    
    /**
     * 仅用于登录兼容的MD5校验（不用于存储）
     */
    private String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException("MD5计算失败", e);
        }
    }
}
